/*cI4u54VYZVPxnvGrX5EL6HXX6+tBhMNbry4zRW5Uf2RuXYfnoeOdBS4xA3fBBRYR*/
//资产卡片
import React, { Component } from 'react';
import { createPage, ajax, base, high, cardCache, cacheTools } from 'nc-lightapp-front';
import {
	buttonClick,
	lockcards,
	initTemplate,
	afterEvent,
	headBeforeEvent,
	pageInfoClick,
	toggleFinanceArea,
	accbookSwitchHandler,
	setStatus,
	rowSelected,
	usedeptButtonClick,
	subequipButtonClick,
	tabShowButtonClick,
	usedeptAfterEvent,
	usedeptBeforeEvent,
	linkToList
} from './events';
import constants from '../constants';
import './index.less';
import BodyTabDataManager from './manager/BodyTabDataManager';
import FaCardCopy from '../components/CardCopy';
import { DepEcharts } from '../components';
import { facard_msg_dataSource } from '../../facard/const';

import ampub from 'ampub';
const { components, commonConst, utils } = ampub;

const { getContext, loginContextKeys } = components.LoginContext;

const { createCardTitleArea, createCardPaginationArea, creatCardSocket } = utils.cardUtils;
const { linkQueryConst } = commonConst.CommonKeys;
const { showMessage } = utils.msgUtils;
const { getMultiLangByID } = utils.multiLangUtils;
const { getThemeUtils } = utils;
import fa from 'fa';
const { fa_utils } = fa;
const { Relogin } = fa_utils;
const { closeWindowWhenRelogin } = Relogin;

const { NCAnchor, NCScrollElement, NCScrollLink, NCAffix, NCBackBtn, NCHotKeys, NCDiv } = base;

const basicInfoForm = constants.AREA.CARD.BASIC_INFO_AREA;
const financeForm = constants.AREA.CARD.FINANCE_AREA;
const tailForm = constants.AREA.CARD.TAIL_AREA;
const alter_tab = constants.AREA.CARD.ALTER_TAB;
const evaluate_tab = constants.AREA.CARD.EVALUATE_TAB;
const reduce_tab = constants.AREA.CARD.REDUCE_TAB;
const devalue_tab = constants.AREA.CARD.DEVALUE_TAB;
const deploy_tab = constants.AREA.CARD.DEPLOY_TAB;
const dep_tab = constants.AREA.CARD.DEP_TAB;
const usedept_tab = constants.AREA.CARD.USEDEPT_TAB;
const subequip_tab = constants.AREA.CARD.SUBEQUIP_TAB;
const assetAllArea = constants.AREA.CARD.ASSET_ALL;
const { FIELDS, assetDataSource, BTN_AREA } = constants;

class Card extends Component {
	constructor(props) {
		super(props);
		this.curr_pk_card = null; //当前pk_card, 用于翻页
		this.curr_transiType = null; //当前transiType, 用于翻页
		this.basicInfoData = {}; // 卡片基本信息（除账簿数据）
		this.assetDataMap = {}; // <pk_accbook, assetVo> 的数据映射
		this.assetDataMapBack = {}; //assetDataMap 的备份
		this.cardVoAttributes = []; //CardVO 的属性列表
		this.business_accbook = ''; //业务账簿
		this.editAbleBook = []; //可编辑的账簿
		this.depmethodFormulaFieldMap = {}; //折旧方法公式字段
		this.depmethods = []; //折旧方法列表
		this.fa10param = {}; //FA10 参数<pk_accbook, boolean>
		this.accbookCurrency = {}; //账簿币种 参数<pk_accbook, pk_currency_book>
		this.fa83param = false; //--支持多成本中心分摊	否（默认值）(集团级数据)
		this.is_allow_dept_midlev = false; //是否允许部门非末级(组织级数据)
		this.basicInfoFields = []; //基本信息区域字段
		this.financeFields = []; //财务区域字段

		this.facardCopy = new FaCardCopy('card');
		this.bodyTabDataManager = new BodyTabDataManager(this); //表体页签数据管理
		this.templateid = '';

		this.editCategoryWhenUpdate = false; //在修改卡片时是否修改了资产类别
		this.reviseFields = []; //允许修订的字段

		this.state = {
			asset_name: '', //资产名称this.
			asset_code: '', //资产编码
			assetuser: '', //使用人
			usedept: '', //使用部门
			usedeptIsNotNull: true, //模板中的使用部门是否不能为空的标志
			mandeptIsNotNull: true, //模板中的管理部门是否不能为空的标志
			pageCode: '', //页面pageid, 也是交易类型的code
			financeShowFlag: false, //财务区展开标志
			accbooks: [], //账簿数组 [{pk_accbook, accbookName}]
			currentPkaccbook: '', //当前选中的账簿

			transiTypeAry: [], //卡片交易类型

			//usedeptScales: [], //多使用部门的数据
			dep_tab_style: 'table', //折旧记录
			depEchartsData: {}, //折旧记录echarts数据
			depEchartsHide: true //折旧记录echarts显示控制
		};

		this.getAccbookDataByPkaccbook.bind(this);
		this.getAccbookDataByPkaccbook4Form.bind(this);
		this.getBasicInfoData4Form.bind(this);
		this.getDataBack.bind(this);
		this.getAssitParam.bind(this);
		this.syncDataForCommit.bind(this);
		this.parseAssetData.bind(this);
		this.setAssetSimpInfo.bind(this);
		this.getDepTableHead.bind(this);
		this.doInit.bind(this);
		this.backToList.bind(this);
		this.setValue.bind(this);
		this.updateAssetCache.bind(this);
		this.getPkcardFromUrl.bind(this);
		this.getPkcardFromClientKey.bind(this);
		this.getPkaccbookByPkcardHis.bind(this);
		this.resetOnAdd.bind(this);
		this.financeOrgInit.bind(this);
		this.clearBodies.bind(this);
		this.setFAParam.bind(this);
		this.updateAssetCacheOnSocketMsg.bind(this);
	}

	componentDidMount() {
		const that = this;
		let status = that.props.getUrlParam('status');
		closeWindowWhenRelogin(this, {
			formid: basicInfoForm,
			statusControl: constants.UISTATE.EDIT
		});

		this.doInit()
			.then((data) => {
				return initTemplate.call(that, that.props);
			})
			.then(() => {
				//判断是否来源于消息打开
				let facard_msg = getContext('facard_msg', facard_msg_dataSource);
				if (facard_msg) {
					let { BillCard, FAParam } = facard_msg;
					this.setValue(BillCard);
					this.setFAParam(FAParam);
				} else {
					//请求数据
					if (status !== constants.UISTATE.ADD) {
						//如果来源于联查: id 的值是 pk_card; 否则是 pk_cardhistory
						let pk = that.props.getUrlParam('id');
						let scene = that.props.getUrlParam(linkQueryConst.SCENE);
						let sceneParam = {};

						if (scene === linkQueryConst.SCENETYPE.linksce) {
							//来源于联查，联查分两个场景：
							//1、联查卡片最小未结账月的数据
							//2、联查卡片历史期间的数据（通过判断 pk_cardhistory）

							// 联查到卡片有两种方式
							// 方式一：通过公共方法 ampub 中 openAssetCardByPk 联查卡片
							let linkParam = cacheTools.get('fa_facard_linkQuery_param');
							//console.log(' ------------- cacheTools.get(fa_facard_linkQuery_param)  ', linkParam);
							if (linkParam) {
								sceneParam = {
									pk_cardhistory: linkParam['pk_cardhistory'],
									pk_accbook: linkParam['pk_accbook'],
									accyear: linkParam['accyear'],
									period: linkParam['period']
								};
								//删除缓存
								cacheTools.remove('fa_facard_linkQuery_param');
							}

							// 方式二：通过 页面编码或交易类型 + pk_card, 多用于外领域联查卡片（比如事务错误中心联查到卡片）
							// 这里已支持
						} else {
							//取出真正的 卡片主键
							let pk2ClientKeyMap = cardCache.getDefData(constants.pk2ClientKeyMap, assetDataSource);
							let clientKey = pk2ClientKeyMap ? pk2ClientKeyMap[pk] : '';
							pk = this.getPkcardFromClientKey(clientKey);
							this.state.currentPkaccbook = this.getPkaccbookByPkcardHis();
						}
						if (pk) {
							//console.log('------------ 打开节点 根据 pk 查询数据， pk = ', pk);
							return that.getData(pk, sceneParam);
						}
					} else {
						this.financeOrgInit();
					}
					setStatus.call(that, that.props);
				}
			})
			.then(
				/* 查询数据成功回调  */
				(data) => {
					if (data) {
						that.getDataBack(data);
						if (status === constants.UISTATE.EDIT) {
							buttonClick.call(that, that.props, constants.CARD_BTNS.HEAD.EDIT);
						}
					}
				},
				(obj) => {
					//查询卡片错误之后，将卡片从缓存和列表中删除
					let scene = that.props.getUrlParam(linkQueryConst.SCENE);
					if (scene !== linkQueryConst.SCENETYPE.linksce) {
						obj['pk_cardhistorys'] = [ that.props.getUrlParam('id') ];
						that.updateAssetCache(obj, 'del');
					}
					setStatus.call(that, that.props, constants.UISTATE.BLANK);
				}
			);
	}

	//初始化
	doInit() {
		const that = this;
		const promise = new Promise(function(resolve, reject) {
			ajax({
				url: constants.URL.INIT,
				data: {},
				success: (res) => {
					let { success, data } = res;
					if (success) {
						that.cardVoAttributes = data.cardVoAttributes;
						that.fa83param = data.FA83;
						that.state.transiTypeAry = data.billTypeAry;

						if (data.msgs && data.msgs.length) {
							showMessage(that.props, { content: data.msgs.join(','), color: 'warning' });
						}

						resolve(data);
					} else {
						reject(data);
					}
				},
				error: (err) => {
					showMessage(that.props, { content: err.message, color: 'danger' });
					reject(err);
				}
			});
		});
		return promise;
	}

	componentWillMount() {
		// 监听浏览器关闭
		window.onbeforeunload = () => {
			// 解锁卡片
			let status = this.props.getUrlParam('status');
			if (status === 'edit') {
				if (!!window.ActiveXObject || 'ActiveXObject' in window) {
					//IE11浏览器（同步解锁）
					lockcards.call(this, 'unlock', false);
				} else {
					//其它浏览器（异步解锁）
					lockcards.call(this, 'unlock', true);
				}
			}
			//浏览器回退键
			if (window.history && window.history.pushState) {
				window.onpopstate = () => {
					lockcards.call(this, 'unlock', false);
				};
			}
		};

		//关闭浏览器页签事件
		window.onunload = () => {

		/*ajax({
				url: '/nccloud/fa/fapub/diagnose.do',
				success: (res) => {
				}
			});*/
			// 清除自定义缓存
			this.state.transiTypeAry.map((transiTypeVo)=> {
				cardCache.setDefData(transiTypeVo.pk_billtypecode, constants.templateDataSource, '');
			});
		};
	}

	// 移除事件
	componentWillUnmount() {
		window.onbeforeunload = null;
	}

	//设置FA 参数（【修改】卡片、打开消息时）
	setFAParam(paramVO) {
		this.depmethodFormulaFieldMap = paramVO['depmethodFormulaFieldMap']; //折旧方法公式字段
		this.depmethods = paramVO['depmethods']; //折旧方法列表
		this.fa10param = paramVO['fa10param'] || {}; //FA10 参数<pk_accbook, boolean>
		this.accbookCurrency = paramVO['accbookCurrency'] || {}; //账簿币种
		this.is_allow_dept_midlev = paramVO['is_allow_dept_midlev'];
		this.isHeadAssetFinanceorg = paramVO['isHeadAssetFinanceorg'];
		// 设置附属设备页签的精度，新增的时候没有编辑后事件，所以在这里设置一下
		this.props.cardTable.setColScale([
			{
				areacode: subequip_tab,
				fieldcode: 'originvalue',
				scale: paramVO['org_digit']
			}
		]);
	}

	//新增时重置数据
	resetOnAdd() {
		this.curr_pk_card = null;
		this.assetDataMap = {};
		this.assetDataMapBack = {};
		this.business_accbook = '';
		this.is_allow_dept_midlev = false;
		this.basicInfoData = {};
		this.editCategoryWhenUpdate = false;

		//清空表单及表格
		this.props.form.EmptyAllFormValue(basicInfoForm);
		if (this.state.financeShowFlag) {
			this.props.form.EmptyAllFormValue(financeForm);
		}

		this.setState({
			asset_name: '',
			asset_code: '',
			assetuser: '',
			usedept: '',
			usedeptIsNotNull: true,
			mandeptIsNotNull: true,
			accbooks: [],
			currentPkaccbook: '',
			financeShowFlag: false //财务区展开标志

			//usedeptScales: [] //多使用部门的数据
		});
		this.clearBodies();
	}

	//清空表体
	clearBodies() {
		this.bodyTabDataManager = new BodyTabDataManager(this); //表体页签数据管理
		const status = this.props.getUrlParam('status');
		let tabs = constants.CARD_ALL_TABS;
		if (status !== constants.UISTATE.BROWSE) {
			tabs = [ constants.AREA.CARD.SUBEQUIP_TAB, constants.AREA.CARD.USEDEPT_TAB ];
		}

		let mulTableData = {};
		tabs.map((tab) => {
			mulTableData[tab] = { rows: [] };
		});
		this.props.cardTable.setMulTablesData(mulTableData);
		//收起表体
		this.props.cardTable.toggleCardTable(tabs, false);
		//清空折旧记录 ECharts 数据
		this.setState(
			{
				depEchartsData: {},
				depEchartsHide: true,
				dep_tab_style: 'table'
			},
			() => {
				//折旧记录页签：如果之前展示的是 Echarts图，切换到 cardTable 需要特殊处理（上面清空方法不起作用-因为当时折旧的表格并不在界面上）
				this.props.cardTable.setMulTablesData({ [dep_tab]: { rows: [] } });
				//收起表体
				this.props.cardTable.toggleCardTable(dep_tab, false);
			}
		);
	}

	//财务组织字段初始化
	financeOrgInit() {
		//获取个性化中心的设置
		let pk_org = getContext('pk_org', assetDataSource);
		let org_Name = getContext('org_Name', assetDataSource);
		if (pk_org) {
			this.props.form.setFormItemsValue(basicInfoForm, {
				pk_org: {
					value: pk_org,
					display: org_Name
				}
			});
			afterEvent.call(this, this.props, basicInfoForm, 'pk_org', { display: org_Name, value: pk_org });
		} else {
			//console.log('------ 调用处于1   initMetaByPkorg');
			this.props.initMetaByPkorg('pk_org');
		}
	}

	//通过卡片主键（pk_card）查询数据, 第二个参数用于联查的扩展（TODO主要是需要后台扩展，目前只实现了 pk_cardhistory）
	getData = (pk_card, { pk_cardhistory = '', pk_accbook = '', accyear = '', period = '' } = {}) => {
		const that = this;
		let url = constants.URL.QUERY_CARD;
		let param = {
			pk: pk_card,
			pagecode: this.state.pageCode,
			queryCondition: {
				templateid: this.templateid
			}
		};
		if (pk_cardhistory || (pk_accbook && accyear && period)) {
			//来源于联查
			url = constants.URL.QUERY_CARD_LINKED;
			param = {
				linkQueryAssetData: {
					pk_cardhistory,
					pk_accbook,
					accyear,
					accmonth: period
				},
				templetid: this.templateid,
				pagecode: this.state.pageCode,
				linktype: '', //来源的类型：用来区别来自于哪个地方的联查
				pk_card //卡片主键
			};
		}

		const promise = new Promise(function(resolve, reject) {
			ajax({
				url,
				data: param,
				success: (res) => {
					let { success, data } = res;
					if (success && data) {
						resolve(data);
					} else {
						/*国际化处理：指定的卡片不存在*/
						showMessage(that.props, { content: getMultiLangByID('201201504A-000025'), color: 'warning' });
						//从缓存中删除
						let obj = {
							pk_card
						};
						reject(obj);
					}
				},
				error: (err) => {
					showMessage(that.props, { content: err.message, color: 'danger' });
					let obj = {
						pk_card
					};
					reject(obj);
				}
			});
		});
		return promise;
	};

	getDataBack = (data) => {
		this.setValue(data);
		//更新缓存
		//这里判断是否来至于联查场景，联查需要更新列表缓存
		let opr = 'update';
		let scene = this.props.getUrlParam(linkQueryConst.SCENE);
		if (scene === linkQueryConst.SCENETYPE.linksce) {
			opr = 'add';
			//清除 url 中的联查标志，并设置 id = pk_cardhistory
			let pk_cardhistorys = this.getBodyAttributeValue(data, 'pk_cardhistory');
			if (pk_cardhistorys && pk_cardhistorys.length) {
				// 清空联查标志
				this.props.setUrlParam({
					id: pk_cardhistorys[0],
					[linkQueryConst.SCENE]: ''
				});
			} else {
				//console.log('------ 这里发生了数据错误 ERR_DATA_001 ------');
			}
		}
		this.updateAssetCache(data, opr);
	};

	//给界面设值
	setValue = (data) => {
		if (data.heads) {
			let assetAllData = [];
			data.heads.forEach((head) => {
				if (head.assetAll && head.assetAll.rows && head.assetAll.rows.length > 0) {
					assetAllData = assetAllData.concat(head.assetAll.rows);
				}
			});
			if (assetAllData.length > 0) {
				this.parseAssetData({ rows: assetAllData });
			}
		}

		if (data.bodysMap) {
			let tabs = Object.keys(data.bodysMap);
			for (let tab of tabs) {
				let tabData = data.bodysMap[tab][tab];
				this.props.cardTable.setTableData(tab, tabData);
				this.bodyTabDataManager.setTabVOs(
					this.curr_pk_card,
					this.state.currentPkaccbook,
					tab,
					JSON.parse(JSON.stringify(tabData))
				);
			}
		}

		let pk_card = this.getHeadAttributeValue(data, 'pk_card');
		this.curr_pk_card = pk_card;

		this.setAssetSimpInfo();

		setStatus.call(this, this.props);
	};

	convertNatureMonthDisplay(naturemonth) {
		//计算 naturemonth_display
		if (naturemonth) {
			try {
				naturemonth = parseInt(naturemonth);
				let year = parseInt(naturemonth / 12);
				let month = parseInt(naturemonth % 12);
				let naturemonth_display = year + '年' + month + '月';
				return {
					value: naturemonth + '',
					display: naturemonth_display
				};
			} catch (e) {
				/*国际化处理：【使用月限】转换错误*/
				showMessage(this.props, { content: getMultiLangByID('201201504A-000008'), color: 'danger' });
			}
		}
	}

	/**
     * 更新缓存数据
     * @param data 数据格式为 getData 返回的数据格式(del 除外)
     * @param opr  有三种状态： add\update\del
     * @param isUpdateListCache  是否更新列表态数据
     * */
	updateAssetCache = (data, opr, isUpdateListCache = true) => {
		if (opr === 'add') {
			const pk_card = this.getHeadAttributeValue(data, 'pk_card');
			//缓存卡片数据（自己缓存的）
			cardCache.setDefData(pk_card, assetDataSource, data);

			//是否更新列表缓存
			if (isUpdateListCache) {
				//更新 pk_cardhistory -> clientKeys 的缓存
				let pk2ClientKeyMap = cardCache.getDefData(constants.pk2ClientKeyMap, assetDataSource);

				let cardPaginationId = '';
				data.heads.map((head, index) => {
					let row = head.assetAll.rows[0];
					//每个账簿调用一次缓存
					const pkvalue = row.values.pk_cardhistory.value;
					if (index === 0) {
						cardPaginationId = pkvalue;
					}
					//更新平台缓存（列表态的缓存）
					cardCache.addCache(pkvalue, null, null, assetDataSource, row.values);
					pk2ClientKeyMap[pkvalue] = row.values.pk_card.value + '_' + row.values.pk_accbook.value;
				});

				// 设置翻页控件当前id
				this.props.cardPagination.setCardPaginationId({ id: cardPaginationId });
				cardCache.setDefData(constants.pk2ClientKeyMap, assetDataSource, pk2ClientKeyMap);
			}
		} else if (opr === 'update') {
			const pk_card_update = this.getHeadAttributeValue(data, 'pk_card');
			//缓存卡片数据（自己缓存的）
			cardCache.setDefData(pk_card_update, assetDataSource, data);

			//更新 pk_cardhistory -> clientKeys 的缓存  (来源于类别的改变会更改 pk_cardhistory 的值，所有这里统一更新一下即使没有发生变化)
			let pk2ClientKeyMap = cardCache.getDefData(constants.pk2ClientKeyMap, assetDataSource);

			if (isUpdateListCache) {
				data.heads.map((head) => {
					let row = head.assetAll.rows[0];
					//每个账簿调用一次缓存
					const pkvalue = row.values.pk_cardhistory.value;
					//更新平台缓存（列表态的缓存）
					cardCache.updateCache('pk_cardhistory', pkvalue, null, null, assetDataSource, row.values);
					pk2ClientKeyMap[pkvalue] = row.values.pk_card.value + '_' + row.values.pk_accbook.value;
				});
				cardCache.setDefData(constants.pk2ClientKeyMap, assetDataSource, pk2ClientKeyMap);
			}
		} else if (opr === 'del') {
			const { pk_card, pk_cardhistorys } = data;
			//缓存卡片数据（自己缓存的）
			cardCache.setDefData(pk_card, assetDataSource, undefined);

			if (isUpdateListCache) {
				pk_cardhistorys.map((pk_cardhistory) => {
					cardCache.deleteCacheById('pk_cardhistory', pk_cardhistory, assetDataSource);
				});
			}
		}
	};

	// 接收 socket 消息时更新缓存
	updateAssetCacheOnSocketMsg = (socketMsg) => {
		if (socketMsg.type === 'saga_error' && socketMsg.refreshData && socketMsg.refreshData.length) {
			let refreshData = socketMsg.refreshData[0];
			let assetvos = Object.values(this.assetDataMap);
			for (let assetvo of assetvos) {
				assetvo.values.saga_status.value = refreshData.saga_status;
				assetvo.values.saga_gtxid.value = refreshData.saga_gtxid;
				//每个账簿调用一次缓存
				const pkvalue = assetvo.values.pk_cardhistory.value;
				//更新平台缓存（列表态的缓存）
				cardCache.updateCache('pk_cardhistory', pkvalue, null, null, assetDataSource, assetvo.values);
			}
		}
	};

	//从后台返回的数据中获取表头字段的属性值: 只适合获取业务字段
	getHeadAttributeValue = (data, field) => {
		if (data.heads && data.heads.length) {
			let assetAll = data.heads[0] && data.heads[0].assetAll && data.heads[0].assetAll.rows[0];
			return assetAll.values[field].value;
		}
	};

	//从后台返回的数据中获取表体字段的属性值: 取历史表中的字段数据
	getBodyAttributeValue = (data, field) => {
		let values = [];
		if (data.heads && data.heads.length) {
			data.heads.map((head) => {
				let row = head.assetAll.rows[0];
				//每个账簿调用一次缓存
				const pkvalue = row.values[field].value;
				values.push(pkvalue);
			});
		}
		return values;
	};

	// 解析表头数据
	parseAssetData = (assetAllData) => {
		let { rows } = assetAllData;
		let assetDataMap = {};
		let accbooks = [];
		let business_accbook = '';
		for (let row of rows) {
			const pk_accbook = row['values']['pk_accbook'].value;
			const accbookName = row['values']['pk_accbook'].display;

			//表头使用部门字段处理:如果是多使用部门，则清空使用部门的字段
			const usedep_flag = row['values']['usedep_flag'].value;
			if (usedep_flag) {
				row['values']['pk_usedept'] = { display: null, value: null };
			}

			//使用月限
			let naturemonthDisplay = this.convertNatureMonthDisplay(row['values']['naturemonth'].value);
			if (naturemonthDisplay) {
				row['values']['naturemonth_display'] = naturemonthDisplay;
			}
			if (pk_accbook) {
				accbooks.push({ pk_accbook, accbookName });
				assetDataMap[pk_accbook] = row;
				if (row['values']['business_flag'].value) {
					//设置主账簿
					business_accbook = pk_accbook;
				}
			}
		}
		//如果不存在账簿，直接返回
		if (!accbooks.length) {
			this.props.form.setAllFormValue({
				[basicInfoForm]: assetAllData
			});
			return;
		} else {
			this.business_accbook = business_accbook;
			//给账簿排序，主账簿放在前面
			let accbooksNew = [];
			accbooksNew = accbooks.filter((accbookObj) => {
				return accbookObj['pk_accbook'] === business_accbook;
			});
			accbooksNew = accbooksNew.concat(
				accbooks.filter((accbookObj) => {
					return accbookObj['pk_accbook'] !== business_accbook;
				})
			);
			accbooks = accbooksNew;
		}

		this.assetDataMap = assetDataMap;

		//备份数据
		this.assetDataMapBack = JSON.parse(JSON.stringify(assetDataMap));

		// 如果已经有选中的账簿，则选择该账簿（这里考虑卡片修改时导致账簿切换，之前选中的账簿要包含在新的账簿列表中）
		let pkaccbook = this.state.currentPkaccbook;
		if (pkaccbook) {
			let isContained = accbooks.some((accbookObj) => pkaccbook === accbookObj.pk_accbook);
			if (!isContained) {
				pkaccbook = accbooks[0]['pk_accbook'];
			}
		} else {
			pkaccbook = accbooks[0]['pk_accbook'];
		}

		this.basicInfoData = assetDataMap[pkaccbook];

		this.setState({
			accbooks
		});

		const accbookData4Form = this.getAccbookDataByPkaccbook4Form(pkaccbook);
		const basicInfoData4Form = this.getBasicInfoData4Form();
		this.state.currentPkaccbook = pkaccbook;
		if (this.state.financeShowFlag) {
			this.props.form.setAllFormValue({
				[basicInfoForm]: basicInfoData4Form,
				[financeForm]: accbookData4Form
			});
		} else {
			this.props.form.setAllFormValue({
				[basicInfoForm]: basicInfoData4Form
			});
		}
	};

	//设置卡片浏览态时：卡片头部的简要信息
	setAssetSimpInfo = () => {
		//获取当前多语
		let langIndex = getContext(loginContextKeys.languageIndex, assetDataSource);

		//设置基本信息区域上面的大标题
		let assetName = this.props.form.getFormItemsValue(basicInfoForm, 'asset_name');
		assetName = assetName['asset_name' + (langIndex || '')]; //取当前语种的字段(防止langIndex为空报错)
		assetName = assetName.display || assetName.value;

		let assetCode = this.props.form.getFormItemsValue(basicInfoForm, 'asset_code');
		assetCode = assetCode.display || assetCode.value;

		let assetuser = this.props.form.getFormItemsValue(basicInfoForm, 'pk_assetuser');
		assetuser = assetuser.display || assetuser.value;

		let usedept = this.props.form.getFormItemsValue(basicInfoForm, 'pk_usedept');
		usedept = usedept.display || usedept.value;

		//从表体取数
		if (!usedept) {
			let usedeptNames = this.props.cardTable.getColValue(usedept_tab, 'pk_dept.name');
			let usedeptScales = this.props.cardTable.getColValue(usedept_tab, 'usescale');
			let temps = [];
			usedeptNames.map((name, i) => {
				temps.push(name.value + ':' + usedeptScales[i].value + '%');
			});
			usedept = temps.join(', ');
		}

		this.setState({
			asset_name: assetName, //资产名称
			asset_code: assetCode, //资产编码
			assetuser: assetuser, //使用人
			usedept: usedept //使用部门
		});
	};

	// 从界面上取值，并更新到 state 中
	syncDataForCommit = () => {
		const status = this.props.getUrlParam('status');

		//获取界面上的数据
		let basicInfoFormValue = this.props.form.getAllFormValue(basicInfoForm);
		let financeFormValueCopy = {};

		if (this.state.financeShowFlag) {
			//财务区展开时才进行同步，否则财务区的值全部是null
			const financeFormValue = this.props.form.getAllFormValue(financeForm);
			//只过滤出财务区字段的数据
			this.financeFields.map((field) => {
				financeFormValueCopy[field] = financeFormValue.rows[0].values[field];
			});
		}

		let formValueCopy = Object.assign({}, basicInfoFormValue.rows[0].values, financeFormValueCopy);

		//把业务字段同步到所有账簿
		let busiFields = new Set(this.cardVoAttributes);
		constants.FIELDS.BUSINESS_FIELD.map((f) => {
			busiFields.add(f);
		});
		busiFields = [ ...busiFields ];
		let { assetDataMap } = this;
		for (let pk_accbook in assetDataMap) {
			let asset = assetDataMap[pk_accbook];
			for (let field of busiFields) {
				asset.values[field] = formValueCopy[field];
			}
			if (status === constants.UISTATE.ADD) {
				asset.status = 2;
			} else if (status === constants.UISTATE.EDIT) {
				asset.status = 1;
			}
		}

		//把财务字段同步到当前账簿(前提是 financeShowFlag=true, 即财务区的form是显示的，不然取到的数据全部是null)
		if (this.state.currentPkaccbook && this.state.financeShowFlag) {
			let currAccbookAsset = assetDataMap[this.state.currentPkaccbook];
			for (let field of constants.FIELDS.ACCOUNT_FIELD) {
				currAccbookAsset.values[field] = formValueCopy[field];
			}
		}
	};

	// 根据 pk_accbook 获取账簿数据
	getAccbookDataByPkaccbook = (pk_accbook) => {
		return this.assetDataMap[pk_accbook];
	};
	// 根据 pk_accbook 获取 适用于 form 格式的数据 （给finance form 设置值只能通过该方法）
	getAccbookDataByPkaccbook4Form = (pk_accbook) => {
		const data = this.assetDataMap[pk_accbook];
		if (data) {
			return { rows: [ JSON.parse(JSON.stringify(data)) ] };
		} else {
			return null;
		}
	};

	// 获取 basicInfo 适用于 form 格式的数据
	getBasicInfoData4Form = () => {
		if (this.basicInfoData) {
			return { rows: [ this.basicInfoData ] };
		} else {
			return null;
		}
	};

	//生成更新保存需要的辅助参数 必须在 syncDataForCommit 执行完之后调用，否则数据可能不准确
	getAssitParam = () => {
		let param = {};
		const pk_card = this.basicInfoData.values['pk_card'].value;
		if (pk_card) {
			param[pk_card] = {};
			//是否修改了资产类别
			const pk_category_old =
				this.assetDataMapBack[this.state.currentPkaccbook] &&
				this.assetDataMapBack[this.state.currentPkaccbook].values['pk_category'].value;
			const pk_category_new = this.basicInfoData.values['pk_category'].value;
			if (pk_category_old !== pk_category_new) {
				param[pk_card]['editCategoryWhenUpdate'] = true;
			} else {
				let pk_accbooks_old = new Set();
				Object.values(this.assetDataMapBack).map((assetvo) => {
					pk_accbooks_old.add(assetvo.values.pk_accbook.value);
				});
				param[pk_card]['editCategoryWhenUpdate'] =
					this.state.accbooks.length !== pk_accbooks_old.size ||
					this.state.accbooks.some((accbook) => !pk_accbooks_old.has(accbook.pk_accbook));
			}
			param[pk_card]['editCategoryWhenUpdate'] =
				pk_category_old !== pk_category_new || this.editCategoryWhenUpdate;
		}
		return param;
	};

	//多使用部门页签肩部的按钮
	getUsedeptTableHead() {
		let status = this.props.getUrlParam('status');
		if (status === constants.UISTATE.BROWSE) {
			return '';
		}
		let { createButtonApp } = this.props.button;

		return (
			<div className="shoulder-definition-area">
				<div className="definition-icons" />
				{createButtonApp({
					area: 'card_body1',
					buttonLimit: 10,
					onButtonClick: usedeptButtonClick.bind(this)
				})}
			</div>
		);
	}

	//附属设备页签肩部的按钮
	getSubequipTableHead() {
		let status = this.props.getUrlParam('status');
		if (status === constants.UISTATE.BROWSE) {
			return '';
		}
		let { createButtonApp } = this.props.button;
		return (
			<div className="shoulder-definition-area">
				<div className="definition-icons">
					{createButtonApp({
						area: 'card_body',
						buttonLimit: 10,
						onButtonClick: subequipButtonClick.bind(this)
					})}
				</div>
			</div>
		);
	}

	//计提记录页签肩部的按钮
	getDepTableHead = () => {
		let { createButtonApp } = this.props.button;

		return (
			<div className="shoulder-definition-area">
				<div className="definition-icons">
					{createButtonApp({
						area: 'card_body2',
						buttonLimit: 10,
						onButtonClick: () => {
							this.setState({ dep_tab_style: 'echarts' });
						}
					})}
				</div>
			</div>
		);
	};

	//计提记录从echarts状态切换回table状态
	onReturnTable = () => {
		this.setState({ dep_tab_style: 'table' }, () => {
			tabShowButtonClick.call(this, this.props, dep_tab, true);
		});
	};

	//返回列表页
	backToList = () => {
		linkToList(this.props);
	};

	//从 url 地址栏中获取 pk_card
	getPkcardFromUrl = () => {
		let pk_card = this.props.getUrlParam('id');
		let scene = this.props.getUrlParam(linkQueryConst.SCENE);
		if (scene !== linkQueryConst.SCENETYPE.linksce) {
			//取出真正的 卡片主键
			let pk2ClientKeyMap = cardCache.getDefData(constants.pk2ClientKeyMap, assetDataSource);
			let clientKey = pk2ClientKeyMap ? pk2ClientKeyMap[pk_card] : '';
			pk_card = this.getPkcardFromClientKey(clientKey);
		}
		return pk_card;
	};

	//根据 URL 中 pk_cardhistory 获取当前需要显示的账簿
	getPkaccbookByPkcardHis = () => {
		let pk_accbook = '';
		let scene = this.props.getUrlParam(linkQueryConst.SCENE);
		if (scene !== linkQueryConst.SCENETYPE.linksce) {
			let pk = this.props.getUrlParam('id');
			//取出真正的 卡片主键
			let pk2ClientKeyMap = cardCache.getDefData(constants.pk2ClientKeyMap, assetDataSource);
			let clientKey = pk2ClientKeyMap ? pk2ClientKeyMap[pk] : '';
			if (clientKey && clientKey.indexOf('_') > -1) {
				pk_accbook = clientKey.split('_')[1];
			}
		}
		return pk_accbook;
	};

	getPkcardFromClientKey = (clientKey) => {
		let pk_card = '';
		if (clientKey && clientKey.indexOf('_') > -1) {
			pk_card = clientKey.split('_')[0];
		}
		return pk_card;
	};

	//楼梯导航点击
	stairNavClick = (moudleId) => {
		if (![ basicInfoForm, financeForm ].includes(moudleId)) {
			this.props.cardTable.toggleCardTable(moudleId, true);
		} else if (financeForm === moudleId) {
			//展开财务区域
			toggleFinanceArea.call(this);
		}
	};

	render() {
		let { cardTable, form, button, modal, ncmodal, pageConfig, ncUploader } = this.props;
		let { createNCUploader } = ncUploader;
		let { createForm } = form;
		let { createCardTable } = cardTable;
		let { createErrorFlag, createButtonApp } = button;
		let { createModal } = modal;

		//获取模板中财务区的名称
		const meta = this.props.meta.getMeta();
		const financeAreaName = meta[financeForm] && meta[financeForm]['name'];

		// 行为相似的tab页 统一进行处理
		const tabsBehaviorAlike = [ dep_tab, alter_tab, evaluate_tab, reduce_tab, devalue_tab, deploy_tab ];

		let status = this.props.getUrlParam('status');

		let navigatorOnBrowse = [
			{ id: basicInfoForm, name: getMultiLangByID('201201504A-000038') /* 国际化处理： 基本信息*/ },
			{ id: financeForm, name: getMultiLangByID('201201504A-000039') /* 国际化处理： 财务区 */ },
			{ id: subequip_tab, name: getMultiLangByID('201201504A-000040') /* 国际化处理： 附属设备 */ },
			{ id: dep_tab, name: getMultiLangByID('201201504A-000041') /* 国际化处理： 折旧记录 */ },
			{ id: alter_tab, name: getMultiLangByID('201201504A-000042') /* 国际化处理： 变动记录 */ },
			{ id: evaluate_tab, name: getMultiLangByID('201201504A-000043') /* 国际化处理： 评估记录 */ },
			{ id: reduce_tab, name: getMultiLangByID('201201504A-000044') /* 国际化处理： 减少记录 */ },
			{ id: devalue_tab, name: getMultiLangByID('201201504A-000045') /* 国际化处理： 减值记录 */ },
			{ id: deploy_tab, name: getMultiLangByID('201201504A-000046') /* 国际化处理： 调拨记录 */ },
			{ id: usedept_tab, name: getMultiLangByID('201201504A-000047') /* 国际化处理： 多使用部门 */ }
		];

		let navigatorOnEdit = [
			{ id: basicInfoForm, name: getMultiLangByID('201201504A-000038') /* 国际化处理： 基本信息*/ },
			{ id: financeForm, name: getMultiLangByID('201201504A-000039') /* 国际化处理： 财务区 */ },
			{ id: subequip_tab, name: getMultiLangByID('201201504A-000040') /* 国际化处理： 附属设备 */ },
			{ id: usedept_tab, name: getMultiLangByID('201201504A-000047') /* 国际化处理： 多使用部门 */ }
		];

		let navigationData = navigatorOnBrowse;
		if (status != constants.UISTATE.BROWSE) {
			navigationData = navigatorOnEdit;
		}

		let tableHeadMap = new Map();
		tableHeadMap.set(dep_tab, this.getDepTableHead);

		let depEchartsData = this.state.depEchartsData;

		return (
			<div
				className={`nc-bill-extCard nc-theme-area-bgc ${getThemeUtils() + 'theme'}`}
				id="fa-newasset-facard-card"
			>
				<NCAnchor>
					{navigationData.map((nav) => {
						return meta[nav.id] && meta[nav.id].areaVisible ? (
							<NCScrollLink
								to={nav.id}
								spy={true}
								smooth={true}
								duration={300}
								offset={-100}
								clickFun={this.stairNavClick.bind(this, nav.id)}
							>
								<p>{nav.name}</p>
							</NCScrollLink>
						) : null;
					})}
				</NCAnchor>
				<div className="nc-bill-top-area">
					<NCHotKeys
						keyMap={{
							unLockBtnHandler: 'alt + ctrl + r' //隐藏快捷键 , 用于解锁卡片
						}}
						handlers={{
							unLockBtnHandler: () => {
								//浏览态快捷键解锁卡片
								if (status === constants.UISTATE.BROWSE) {
									// 解锁卡片
									lockcards.call(this, 'unlock');
									showMessage(this.props, { content: 'unLock success.', color: 'success' });
								}
							}
						}}
						// 是否启用组件
						enabled={true}
						// 是否为聚焦触发
						focused={true}
						// 默认display 可以设置 inline-block 等dispaly属性
						display="none"
					/>
					<NCAffix>
						<NCDiv areaCode={NCDiv.config.HEADER} className="nc-bill-header-area">
							{/* 标题区 返回按钮*/}
							<div className="header-title-search-area">
								{createCardTitleArea.call(this, this.props, {
									title: pageConfig.title,
									backBtnClick: this.backToList
								})}
							</div>
							{/* 按钮区 */}
							<div className="header-button-area">
								{/* 创建重试、回退等 saga 状态按钮 */}
								{createErrorFlag({
									headBtnAreaCode: BTN_AREA.CARD_HEAD
								})}
								{createButtonApp({
									area: BTN_AREA.CARD_HEAD,
									onButtonClick: buttonClick.bind(this)
								})}
							</div>
							{/*浏览态增加 上一页/下一页 */}
							{createCardPaginationArea.call(this, this.props, {
								formId: basicInfoForm,
								dataSource: assetDataSource,
								pageInfoClick: pageInfoClick.bind(this)
							})}
						</NCDiv>
					</NCAffix>

					<div className="nc-bill-form-area">
						<NCScrollElement name={basicInfoForm}>
							{/*浏览态 卡片名称 资产编码 使用人 使用部门 放大显示*/}
							{status === constants.UISTATE.BROWSE ? (
								<div className="card-title-area">
									<p>
										<span title={this.state.asset_name}>{this.state.asset_name}</span>
										<span>{this.state.asset_code}</span>
									</p>
									<p>
										<span title={this.state.assetuser}>{this.state.assetuser}</span>
										<span title={this.state.usedept}>{this.state.usedept}</span>
									</p>
								</div>
							) : (
								''
							)}

							{createForm(basicInfoForm, {
								onAfterEvent: afterEvent.bind(this),
								onBeforeEvent: headBeforeEvent.bind(this)
							})}
						</NCScrollElement>

						{/* 财务核算账簿 */}
						<NCScrollElement name={financeForm}>
							<div className="group-form-wrapper">
								{
									<NCDiv
										className="group-form-name finance-group-name"
										areaCode={NCDiv.config.Group}
										fieldid={financeForm}
									>
										<div onClick={toggleFinanceArea.bind(this)}>
											<span className="name">
												<span className="name-icon">
													{this.state.financeShowFlag ? '-' : '+'}
												</span>
												{financeAreaName || ''}
											</span>
											<span className="finance-line" />
										</div>
									</NCDiv>
								}
								{this.state.financeShowFlag && (
									<div>
										{/* 账簿按钮*/}
										<div className="accbook-btn-area group-form-name">
											{this.state.accbooks.map((accbook) => (
												<span
													className={`name ${this.state.currentPkaccbook == accbook.pk_accbook
														? 'accbook-checked'
														: ''}`}
													onClick={accbookSwitchHandler.bind(this, accbook.pk_accbook)}
													key={accbook}
												>
													{accbook.accbookName}
												</span>
											))}
										</div>

										<div>
											{createForm(financeForm, {
												onAfterEvent: afterEvent.bind(this),
												onBeforeEvent: headBeforeEvent.bind(this)
											})}
										</div>
									</div>
								)}
							</div>
						</NCScrollElement>
					</div>
				</div>

				<div className="nc-bill-bottom-area">
					<div className="nc-bill-tableTab-area">
						{/* 附属设备 */}
						<NCScrollElement name={subequip_tab}>
							{createCardTable(subequip_tab, {
								tableHead: this.getSubequipTableHead.bind(this),
								onHeadAngleToggle: tabShowButtonClick.bind(this),
								selectedChange: rowSelected.bind(this),
								showCheck: true,
								showIndex: true
							})}
						</NCScrollElement>
					</div>

					<div className={status === constants.UISTATE.BROWSE ? 'cardTable-show' : 'cardTable-hide'}>
						{/*仅需要在浏览态显示的页签，且行为操作基本相同*/}
						{tabsBehaviorAlike.map((tab) => {
							if (tab === 'dep_tab') {
								return (
									<div className="nc-bill-tableTab-area dep_tab_area" key={tab}>
										<NCScrollElement name={tab}>
											{this.state.dep_tab_style === 'table' ? (
												createCardTable(tab, {
													tableHead: tableHeadMap.get(tab),
													onHeadAngleToggle: tabShowButtonClick.bind(this),
													showIndex: true,
													showMore: false
												})
											) : (
												<DepEcharts
													{...this.props}
													onReturnTable={this.onReturnTable}
													seriesData={depEchartsData}
													hide={this.state.depEchartsHide}
												/>
											)}
										</NCScrollElement>
									</div>
								);
							}
							return (
								<div className="nc-bill-table-area" key={tab}>
									<NCScrollElement name={tab}>
										{createCardTable(tab, {
											tableHead: tableHeadMap.get(tab),
											onHeadAngleToggle: tabShowButtonClick.bind(this),
											showCheck: true,
											showIndex: true
										})}
									</NCScrollElement>
								</div>
							);
						})}
					</div>

					<div className="nc-bill-tableTab-area">
						{/* 多使用部门 */}
						<NCScrollElement name={usedept_tab}>
							{createCardTable(usedept_tab, {
								tableHead: this.getUsedeptTableHead.bind(this),
								onHeadAngleToggle: tabShowButtonClick.bind(this),
								selectedChange: rowSelected.bind(this),
								onBeforeEvent: usedeptBeforeEvent.bind(this),
								onAfterEvent: usedeptAfterEvent.bind(this),
								showCheck: true,
								showIndex: true
							})}
						</NCScrollElement>
					</div>
				</div>

				{createModal(constants.MODAL_ID.CopyModal, {
					title: getMultiLangByID('201201504A-000026') /* 国际化处理： 卡片复制 */,
					content: this.facardCopy.copyCardDialog(this),
					userControl: true,
					className: 'combine'
				})}
				{/* 附件*/}
				{createNCUploader('uploader', {})}
				{/* 预警提示框 */}
				{createModal(constants.MODAL_ID.ConfirmModal, { color: 'warning' })}

				{/* 创建 socket 链接 */}
				{creatCardSocket.call(this, this.props, {
					headBtnAreaCode: BTN_AREA.CARD_HEAD, // 按钮区域编码,用于平台内部更新按钮状态
					formAreaCode: basicInfoForm, //表单区域编码, 用于平台内部更新表头数据
					onMessage: (props, msg) => {
						//监听消息
						// 仅处理自己的按钮显示控制，重试和回退按钮有平台处理
						this.updateAssetCacheOnSocketMsg(msg);

						if (msg.error) {
							// 补充事务存在异常时，页面要显示的按钮控制逻辑
							// 由需求定义保留显示按钮逻辑
							// 单据追溯和刷新比较重要，需要显示
						} else {
							// 事务通过重试或回退方式成功时，要恢复按钮显示控制逻辑
						}
					},
					//billtype: pageConfig.billType, //单据类型, 用于查询追溯
					billpkname: constants.FIELDS.HEAD_PK //单据主键名, 用于查询追溯
				})}
			</div>
		);
	}
}

export default Card;

/*cI4u54VYZVPxnvGrX5EL6HXX6+tBhMNbry4zRW5Uf2RuXYfnoeOdBS4xA3fBBRYR*/